﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Data;
using System.Text.RegularExpressions;

namespace Dapper.Library
{
	public class EntityObject
	{
		public EntityObject(Type type,SqlProvider SqlProvider, IDbConnection dbCon = null)
        {
			//反射表名称
			this.Name = type.Name;

            Regex R = new Regex("[A-Z]");
            int index = 0;
            foreach (char s in type.Name)
            {
                index++;
                if (R.IsMatch(s.ToString()))
                {
                    this.AsName +=(s.ToString()+ type.Name.Substring(index, 1)) ;
                }
            }
            
            this.Type = type;
			this.AssemblyString = type.FullName;
			//反射实体类属性
			this.Properties = type.GetProperties();
			List<PropertyInfo> PropertyInfoList = new List<PropertyInfo>();
			//字段字典
			this.FieldPairs = new Dictionary<string, string>();
			//导航列表
			this.Navigations = new List<JoinAssTable>();
			//字段列表
			this.EntityFieldList = new List<EntityField>();
			//反射实体类字段
			foreach (var item in this.Properties)
			{
				//子父类存在相同的字段
				if (this.FieldPairs.Any(x => x.Key == item.Name))
				{
					continue;
				}

				//当前字段属性设置
                var fieldAttribute = item.GetCustomAttribute<DBFieldInfo>();
                if (fieldAttribute != null)
				{
                    //////////////////////////////////LW修改  
                    if (SqlProvider!=null)
                    {
                        if (SqlProvider.ToString().Equals("Dapper.Library.DapperPostgreSql.PostgreSqlProvider"))
                        {
                            this.FieldPairs.Add(item.Name, item.Name);
                        }
                        else
                        {
                            this.FieldPairs.Add(item.Name, fieldAttribute.ColumnName);
                        }
                    }
                    else
                    {
                        this.FieldPairs.Add(item.Name, fieldAttribute.ColumnName);
                    }
                    //获取是否有重命名
                    PropertyInfoList.Add(item);
                    //设置详细属性
                    EntityFieldList.Add(new EntityField()
                    {
                        FieldName = this.FieldPairs[item.Name],
                        PropertyInfo = item,
                        SqlDbType = GetSqlDbType(item.PropertyType), 
                        Length = fieldAttribute.ByteLength,
                        Description = "",
                        IsNull = fieldAttribute.Required==true?false:true,
                        DefaultValue = string.Empty
                    });
                }
                else
				{
					this.FieldPairs.Add(item.Name, item.Name);
					PropertyInfoList.Add(item);

					//设置详细属性
					EntityFieldList.Add(new EntityField()
					{
						FieldName = item.Name,
						PropertyInfo = item,
						SqlDbType = GetSqlDbType(item.PropertyType),
						Length = 0
					});
				}

                //获取主键[自增/非自增]
                if (string.IsNullOrEmpty(this.Primarykey))
                {
                    var dbFieldInfo = item.GetCustomAttribute<DBFieldInfo>();
                    if (dbFieldInfo != null)
                    {
                        if (dbFieldInfo.IsPrimarykey)
                        {
                            //////////////////////////////////LW修改  
                            this.IsIncrease = dbFieldInfo.IsIncrease;
                            this.Primarykey = this.FieldPairs[item.Name];
                            EntityFieldList[EntityFieldList.Count - 1].IsPrimarykey = dbFieldInfo.IsPrimarykey;
                            EntityFieldList[EntityFieldList.Count - 1].IsIncrease = dbFieldInfo.IsIncrease;
                        }
                    }
                }
            }
			this.Properties = PropertyInfoList.ToArray();
		}

        /// <summary>
        /// 主键名称
        /// </summary>
        public string Primarykey { get; set; }

        /// <summary>
        /// 是否自增
        /// </summary>
        public bool IsIncrease { get; set; }

        /// <summary>
        /// 类名(表名称)
        /// </summary>
        public string Name { get; set; }

		/// <summary>
		/// 名称空间
		/// </summary>
		public string Schema { get; set; }

		/// <summary>
		/// 指定as名称
		/// </summary>
		public string AsName { get; set; }

		/// <summary>
		/// 类型
		/// </summary>
		public Type Type { get; set; }

		/// <summary>
		/// 命名空间
		/// </summary>
		public string AssemblyString { get; set; }

		/// <summary>
		/// 类反射的属性实例
		/// </summary>
		public PropertyInfo[] Properties { get; set; }

		/// <summary>
		/// 字段目录(属性名称和实体名称)
		/// </summary>
		public Dictionary<string, string> FieldPairs { get; set; }

		/// <summary>
		/// 导航属性列表
		/// </summary>
		public List<JoinAssTable> Navigations { get; set; }

		/// <summary>
		/// 获取asname
		/// </summary>
		/// <param name="IsAsName"></param>
		/// <returns></returns>
		public string GetAsName(IProviderOption providerOption, bool IsAsName = true, bool IsSuffix = true)
		{
			string asName = string.Empty;
			if (IsAsName)
			{
				asName = this.AsName;
				//////////////////////////////////LW修改/////////////////////////////////
				//如果没有as name，则需要给表带上标记
				//if (asName.Equals(this.Name))
				//	asName = providerOption.CombineFieldName(asName);
				//是否需要后缀
				if (IsSuffix)
					asName += ".";
			}
			return asName;
		}
		/// <summary>
		/// 字段列表
		/// </summary>
		public List<EntityField> EntityFieldList { get; set; }

		/// <summary>
		/// 获取默认数据类型
		/// </summary>
		/// <param name="type"></param>
		/// <returns></returns>
		private SqlDbType GetSqlDbType(Type type)
		{
			//设置数据库字段类型
			SqlDbType sqlDbType = SqlDbType.VarChar;
			if (type == typeof(int))
			{
				sqlDbType = SqlDbType.Int;
			}
			else if (type == typeof(long))
			{
				sqlDbType = SqlDbType.BigInt;
			}
			else if (type == typeof(Guid))
			{
				sqlDbType = SqlDbType.UniqueIdentifier;
			}
			else if (type == typeof(DateTime))
			{
				sqlDbType = SqlDbType.DateTime;
			}
			else if (type == typeof(decimal))
			{
				sqlDbType = SqlDbType.Decimal;
			}
			else if (type == typeof(bool))
			{
				sqlDbType = SqlDbType.Bit;
			}
			return sqlDbType;
		}
	}

	/// <summary>
	/// 实体字段
	/// </summary>
	public class EntityField
	{
        /// <summary>
        /// 是否是主键
        /// </summary>
        public bool IsPrimarykey { get; set; }

        /// <summary>
        /// 是否自增
        /// </summary>
        public bool IsIncrease { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public PropertyInfo PropertyInfo { get; set; }

		/// <summary>
		/// 字段名称
		/// </summary>
		public string FieldName { get; set; }

		/// <summary>
		/// 字段类型
		/// </summary>
		public SqlDbType SqlDbType { get; set; }

		/// <summary>
		/// 字段长度
		/// </summary>
		public int Length { get; set; }

		/// <summary>
		/// 字段描述
		/// </summary>
		public string Description { get; set; }

		/// <summary>
		/// 是否允许为空
		/// </summary>
		public bool IsNull { get; set; } = false;

		/// <summary>
		/// 默认值
		/// </summary>
		public object DefaultValue { get; set; }
	}
}
